<?php

abstract class Gallery_Backend_Utils 
{
    
    /**
    * Filter name.
    * 
    */
    const FILTER = 'category_id';
    
    /**
    * Active filter
    * 
    * @return integer
    */
    static public function activeFilter() 
    {
        return Application::getRequest()->get(self::FILTER)
            ? (int)Application::getRequest()->get(self::FILTER)
            : self::_default();
    }
    
    /**
    * Return default filter id
    * 
    * @return integer
    */
    static private function _default() 
    {
        if ('add' == Application::getRequest()->get('action')) {
            return null;
        }
        
        $entries = Kernel_Util_Tree::convert(self::getCategories());
        
        return isset($entries[0]) ? (int)$entries[0]['id'] : null;
    }
    
    /**
    * @desc Current branch can not be moved to itself and in any of its children.
    * 
    * @param integer $id
    */
    static public function parents($id = null) 
    {
        if (is_null($id)) {
            $id = self::activeFilter();
        }
        
        return self::convertToList(
            Kernel_Util_Tree::non_children(self::getCategories(), $id));
    }
    
    /**
    * @desc Return parent of the current resource. 
    * 
    * @param integer $id
    */
    static public function parent($id = null) 
    {
        if (is_null($id)) {
            $id = self::activeFilter();
        }
        
        foreach (self::getCategories() as $entry) {
            if ($id == $entry['id']) {
                return $entry['parent_id'];
            }
        }
    }
    
    static public function getCategories() 
    {
        static $cach;
        
        if (is_null($cach)) {
            $query = '
                SELECT 
                       `id`, 
                       `parent_id`, 
                       `name` 
                  FROM 
                       `photo_categories` 
              ORDER BY 
                       `position` 
            ';
            
            $cach = database::fetchAll($query);
        }
        
        return $cach;
    }
    
    
    /**
    * @desc Make list from tree entries padding with $symbol $pad times. 
    * 
    * 
    * @param array      $set
    * @param array      &$list
    * @param integer    $pad
    * @param string     $symbol
    */
    static public function convertToList($set, $pad = 2, $symbol = '&nbsp;') 
    {
        $list = array();
        
        self::_list_recursive($set, $list, (int)$pad, $symbol, $inc = 1);
        
        return $list;
    }
    
    /**
    * @desc Apply padding to the value recursively. 
    * 
    * @param array  $set
    * @param array  &$list
    * @param integer $pad
    * @param string $symbol 
    * @param integer $inc
    */
    static private function _list_recursive($set, &$list, $pad, $symbol, $inc) 
    {
        $padding = str_pad('', strlen($symbol)*($pad*$inc), $symbol, STR_PAD_LEFT);
        
        foreach ($set as $node) {
            $list[$node['id']] = $padding . $node['name'];
            
            if (!empty($node['children'])) {
                self::_list_recursive($node['children'], &$list, $pad, $symbol, ++$inc);
            }
            
        }
    }
    
    
    /**
    * Return positions list that can be placed under the specified parent. 
    * 
    * 
    * @param integer    $id 
    * @param integer    $parent_id
    * @return array
    */
    static public function positions($id, $parent_id) 
    {
        $query = '
            SELECT 
                   COUNT(*) 
              FROM 
                   `photo_categories`
             WHERE 
                   `parent_id` ' . (0 == $parent_id ? 'IS NULL' : '= ' . (int)$parent_id);
        $elements_num = database::fetchOne($query);
        
        // check whether declared parent is the same as specified resource has, 
        // otherwise it means that resource is moved within the tree, so place 
        // additional position for it 
        // OR 
        // current resource is 0 (it means that we add a new resource), so also 
        // place additional position 
        $query = '
            SELECT 
                   `parent_id`
              FROM 
                   `photo_categories` 
             WHERE 
                   `id` = ' . (int)$id . '
            ';
        if (database::fetchOne($query) != $parent_id || $id < 1) { 
            $elements_num += 1; 
        }
        
        $positions = range(1, $elements_num);
        return array_combine($positions, $positions);
    }
    
    /**
    * Return element position
    * 
    * @param integer
    * @param integer
    * 
    * @return array
    */
    static public function position($parent_id_src, $id) 
    {
        if ($id > 0) {
            $query = '
                SELECT 
                       `parent_id` `parent_id_dst`, 
                       `position` `position`
                  FROM 
                       `photo_categories` 
                 WHERE 
                       `id` = ' . (int)$id . '
                 ';
            
            $entries = database::fetchRow($query);
            extract($entries);
            return $parent_id_src == $parent_id_dst ? $position : 0;
        } else {
            return self::position_max($parent_id_src) + 1;
        }
    }
    
    /**
    * Return max position of any element or if parent specified then under
    * this parent. 
    * 
    * @param integer $parent
    * 
    * @return integer
    */
    static public function position_max($parent_id = null) 
    {
        $query = '
            SELECT 
                   MAX(`position`)
              FROM 
                   `photo_categories` 
             WHERE 
            ';
        if (!is_null($parent_id)) {
            $query .= '
                      `parent_id` = ' . $parent_id . ' 
                ';
        }
        
        return (int)database::fetchOne($query);
    }
    
}